package com.zsc.tool;

import com.google.gson.Gson;
import com.zsc.tool.serial.Serializer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by xbkaishui on 17/3/7.
 */
public class RedisClient {

    private static final ConcurrentHashMap<RedisConnection, RedisClient> cache =
            new ConcurrentHashMap();
    private RedisConnection conn;
    private static Object lock = new Object();
    private JedisPool pool;

    public RedisClient(RedisConnection conn) {
        this.conn = conn;
        pool = new JedisPool(new JedisPoolConfig(), conn.getHost(), conn.getPort(), 2000,
                conn.getPassword(), Protocol.DEFAULT_DATABASE);
    }

    public static RedisClient instance(RedisConnection conn) {
        RedisClient client = cache.get(conn);
        if (client == null) {
            synchronized (lock) {
                client = new RedisClient(conn);
                cache.putIfAbsent(conn, client);
            }
        }
        return client;
    }

    public void set(String key, Object obj) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = Serializer.serializer(obj);
            String code = jedis.set(key, value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public void setString(String key, String obj) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            jedis.set(key, obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public void set(final String key, final Object obj, final String nxxx, final String expx,
                    final long time) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = Serializer.serializer(obj);
            String code = jedis.set(key, value, nxxx, expx, time);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }


    public String getString(String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = jedis.get(key);
            return value;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }

    }


    public Object get(String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = jedis.get(key);
            if (value == null) {
                return null;
            }
            return Serializer.deSerializer(value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }

    }

    public void setjson(String key, Object obj,Integer expireTime) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = new Gson().toJson(obj);
            String code = jedis.set(key, value);
            if(expireTime!=null){
                jedis.expire(key,expireTime);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public String getjson(String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            String value = jedis.get(key);
            if (value == null) {
                return null;
            }
            return value;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }

    }

    public boolean del(String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            jedis.del(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
        return true;
    }

    public Boolean exists(final String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.exists(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    public Long incr(final String key) {
        Jedis jedis = null;
        try {
            jedis = pool.getResource();
            return jedis.incr(key);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(jedis);
        }
    }

    private void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}
